
package com.x52im.rbchat.logic.sns_group.viewmodel;

import android.util.Log;

import com.eva.framework.dto.DataFromServer;
import com.x52im.rbchat.MyApplication;
import com.x52im.rainbowchat.http.logic.dto.RosterElementEntity;
import com.x52im.rbchat.logic.sns_group.JoinGroupActivity;
import com.x52im.rbchat.network.http.HttpRestHelper;

import net.x52im.mobileimsdk.android.utils.MBThreadPoolExecutor;

import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

/**
 * 二维码扫码加群界面对应的ViewModel实现类。
 *
 * @author JackJiang
 * @since 8.1
 */
public class JoinGroupViewModel extends ViewModel {

    private final static String TAG = JoinGroupViewModel.class.getSimpleName();

    /** 群基本信息数据LiveData对象 */
    private MutableLiveData<DataFromServer> groupInfoLiveData = null;
    /** 这是一个支持多线程原子读的标识量（比布尔量使用更灵活），当载入任务开始时+1、载入任务执行时-1，目的是防止后台线程池任务堆积 */
    private final AtomicInteger loadingGroupInfoCount = new AtomicInteger(0);

    /** 二维码分享者基本信息数据LiveData对象 */
    private MutableLiveData<DataFromServer> sharedByUserInfoLiveData = null;
    /** 这是一个支持多线程原子读的标识量（比布尔量使用更灵活），当载入任务开始时+1、载入任务执行时-1，目的是防止后台线程池任务堆积 */
    private final AtomicInteger loadingSharedByUserInfoCount = new AtomicInteger(0);

    /** 加群提交结果LiveData对象 */
    private MutableLiveData<DataFromServer> joinGroupSubmitLiveData = null;
    /** 这是一个支持多线程原子读的标识量（比布尔量使用更灵活），当载入任务开始时+1、载入任务执行时-1，目的是防止后台线程池任务堆积 */
    private final AtomicInteger joinGroupSubmitCount = new AtomicInteger(0);

    public JoinGroupViewModel() {
        this.initLiveData();
    }

    /**
     * liveData对象初始化。
     */
    private void initLiveData() {
        Log.i(TAG, "@@@@【"+TAG+"】initLiveData被调用了！");

        if (this.groupInfoLiveData == null)
            this.groupInfoLiveData = new MutableLiveData<>();
        if(this.sharedByUserInfoLiveData == null)
            this.sharedByUserInfoLiveData = new MutableLiveData<>();
        if(joinGroupSubmitLiveData == null)
            this.joinGroupSubmitLiveData = new MutableLiveData<>();
    }

    /**
     * 从服务端异步加载群基本信息。
     *
     * @param gid 群id
     */
    public void loadGroupInfo(String gid){
        Log.i(TAG, "@@@@【"+TAG+"】loadGroupInfo。。。。");

        // 加载指示标识（用于防止多线程重复加载）
        int count = loadingGroupInfoCount.get();
        if (count > 0) {
            return;
        }

        // 加载线程开始前指示标识+1
        loadingGroupInfoCount.incrementAndGet();

        // 数据通过网格的获取逻辑在后台进行
        MBThreadPoolExecutor.runInBackground(() -> {
            long t = System.currentTimeMillis();
            // 加载开始后指示标识-1
            loadingGroupInfoCount.decrementAndGet();

            // 获取群基本信息数据
            DataFromServer dfs4GroupInfo = HttpRestHelper.submitGetGroupInfoToServer(gid, null);

            // 将数据通知给观察者（以备ui刷新显示）
            if (groupInfoLiveData != null) {
                groupInfoLiveData.postValue(dfs4GroupInfo);
                Log.i(TAG, "@@@@【"+TAG+"】loadGroupInfo完成，耗时："+(System.currentTimeMillis()-t)+"ms");
            }
        });
    }

    /**
     * 从服务端异步加载二维码分享者的基本信息。
     *
     * @param sharedByUid 二维码分享者的uid
     */
    public void loadSharedByUserInfo(String sharedByUid){
        Log.i(TAG, "@@@@【"+TAG+"】loadSharedByUserInfo。。。。");

        // 加载指示标识（用于防止多线程重复加载）
        int count = loadingSharedByUserInfoCount.get();
        if (count > 0) {
            return;
        }

        // 加载线程开始前指示标识+1
        loadingSharedByUserInfoCount.incrementAndGet();

        // 数据通过网格的获取逻辑在后台进行
        MBThreadPoolExecutor.runInBackground(() -> {
            long t = System.currentTimeMillis();
            // 加载开始后指示标识-1
            loadingSharedByUserInfoCount.decrementAndGet();

            // 获取用户基本信息数据
            DataFromServer dfs4UserInfo = HttpRestHelper.submitGetFriendInfoToServer(false, null, sharedByUid);

            // 将数据通知给观察者（以备ui刷新显示）
            if (sharedByUserInfoLiveData != null) {
                sharedByUserInfoLiveData.postValue(dfs4UserInfo);
                Log.i(TAG, "@@@@【"+TAG+"】loadSharedByUserInfo完成，耗时："+(System.currentTimeMillis()-t)+"ms");
            }
        });
    }

    /**
     * 向服务端异步提交加群请求。
     *
     * @param gid 要加入的群id
     * @param sharedByUid 分享者的uid
     * @param sharedByNickName 分享者的昵称
     * @param joinBy 群聊分享类型
     */
    public void submitJoinGroup(String gid, String sharedByUid, String sharedByNickName, int joinBy){
        Log.i(TAG, "@@@@【"+TAG+"】submitJoinGroup。。。。");

        // 加载指示标识（用于防止多线程重复加载）
        int count = joinGroupSubmitCount.get();
        if (count > 0) {
            return;
        }

        // 加载线程开始前指示标识+1
        joinGroupSubmitCount.incrementAndGet();

        // 数据通过网格的获取逻辑在后台进行
        MBThreadPoolExecutor.runInBackground(() -> {
            long t = System.currentTimeMillis();
            // 加载开始后指示标识-1
            joinGroupSubmitCount.decrementAndGet();

            RosterElementEntity locaUserInfo = MyApplication.getInstance2().getIMClientManager().getLocalUserInfo();
            // 如果本地用户信息读取异常，则直接返回失败的结果给ui层
            if(locaUserInfo == null){
                if (joinGroupSubmitLiveData != null) {
                    joinGroupSubmitLiveData.postValue(DataFromServer.createDefaultFailed());
                }
                return;
            }

            // 组织将要提交给服务端的加群请求数据
            ArrayList<ArrayList> items = new ArrayList<>();
            // 以下字段及顺序请确保与http"【接口1016-24-24】"保持一致（接口参数详见接口方法说明）！
            ArrayList<String> row = new ArrayList<>();
            row.add(gid);
            row.add(locaUserInfo.getUser_uid());
            row.add(locaUserInfo.getNickname());
            // 将加群者信息暂存以备提交给服务端（默认的加群接口是支持多人加群的，所以实际上
            // 此时扫码加群时这个加群者集合中只有"我"一个加群的人）
            items.add(row);

            // 向服务端提交加群请求
            DataFromServer dfs = HttpRestHelper.submitInviteToGroupToServer(joinBy == JoinGroupActivity.JOIN_BY_SCAN_QRCODE ? "1":"2", sharedByUid, sharedByNickName, gid, items);
            // 将请求结果通知给观察者（以备ui刷新显示）
            if (joinGroupSubmitLiveData != null) {
                joinGroupSubmitLiveData.postValue(dfs);
                Log.i(TAG, "@@@@【"+TAG+"】submitJoinGroup完成，耗时："+(System.currentTimeMillis()-t)+"ms");
            }
        });
    }

    public MutableLiveData<DataFromServer> getGroupInfoLiveData() {
        return groupInfoLiveData;
    }

    public MutableLiveData<DataFromServer> getSharedByUserInfoLiveData() {
        return sharedByUserInfoLiveData;
    }

    public MutableLiveData<DataFromServer> getJoinGroupSubmitLiveData() {
        return joinGroupSubmitLiveData;
    }
}
